<script>
let make = go.GraphObject.make;

export default {
  name: "Diagram",
  render (createElement, context) {
    return createElement('div')
  },
  props: {
    modelData: {
      type: Object,
      default: () => ({ nodeDataArray: [], linkDataArray: [] }),
      required: true,
    },
    bdsList: {
      type: Array,
      default: () => ([]),
      required: true,
    },
  },
  data () {
    return {
      ysfObj: {
        "&&": '并且',
        "||": '或者',
        ">": '大于',
        ">=": '大于等于',
        "<": '小于',
        "<=": '小于等于',
        "!=": '不等于',
        "==": '等于',
      },
    }
  },
  mounted () {
    let myDiagram = make(go.Diagram, this.$el, {
      initialContentAlignment: go.Spot.TopLeft,
      layout: make(go.TreeLayout),
      "undoManager.isEnabled": false, // 是否开启撤回管理器-仅对于操作model有效
      "animationManager.isEnabled": false, // 是否开启动画
      "toolManager.mouseWheelBehavior": go.ToolManager.WheelNone,
      isReadOnly: true, // 是否只读
      allowMove: false, // 是否允许移动
      allowSelect: false, // 是否允许选中节点
      ModelChanged: e => this.$emit("model-changed", e),
      ChangedSelection: e => this.$emit("changed-selection", e),
      contextClick: e => this.$hideContextmenu(),
      click: e => this.$hideContextmenu(),
    });
    myDiagram.nodeTemplateMap.add("decision",
        make(go.Node, "Auto", {
              toolTip: make("ToolTip", make(go.TextBlock, { font: "8pt sans-serif", margin: 6 },
                  new go.Binding("text", "", data => this.bdsToZw(data.data.bds)))
              ),
              doubleClick: (e, node) => this.$emit('item-dbclick', e, node),
              contextClick: (e, node) => this.$emit('item-contextmenu', e, node),
            },
            make(go.Picture, {}, new go.Binding("source", "", () => require('@/assets/img/bg.svg'))),
            make(go.Panel, "Horizontal",
                { padding: 10 },
                make(go.TextBlock, { font: "15px Roboto, sans-serif", margin: 5 },
                    new go.Binding("text", "", data => data.data.bds || '双击编辑/修改'),
                    new go.Binding("stroke", "", data => (data.data.bds ? 'black' : 'red')),
                ),
                make(go.Panel, "Vertical",
                    make("Button",
                        { click: (e, node) => this.$emit('add-item', e, node), margin: 3 },
                        make(go.Picture,
                            { height: 16, width: 16, },
                            new go.Binding("source", "", () => require('@/assets/img/true.png'))),
                        new go.Binding("portId", "", () => "yes"),
                        new go.Binding("visible", "", ({ data }) => {
                          if (!data.bds) return true
                          let bdsmcList = data.bds.match(/bds\d+/g)
                          for (let bdsmc of bdsmcList) {
                            let bds = this.bdsList.find(item => item.bdsmc === bdsmc)
                            if (!bds) return false
                            if (bds.bdslx === "TS") return false
                          }
                          return true
                        }),
                    ),
                    make("Button",
                        new go.Binding("portId", "", () => "no"),
                        { click: (e, node) => this.$emit('add-item', e, node), margin: 3 },
                        make(go.Picture,
                            { height: 16, width: 16, },
                            new go.Binding("source", "", () => require('@/assets/img/false.png'))),
                        new go.Binding("visible", "", ({ data }) => {
                          if (!data.bds) return true
                          let bdsmcList = data.bds.match(/bds\d+/g)
                          for (let bdsmc of bdsmcList) {
                            let bds = this.bdsList.find(item => item.bdsmc === bdsmc)
                            if (!bds) return false
                            if (bds.bdslx === "TS") return false
                          }
                          return true
                        }),
                    )
                )
            )
        )
    );

    // myDiagram.linkTemplate = make(go.Link,
    //     { relinkableFrom: true, relinkableTo: true },
    //     make(go.Shape),
    //     make(go.Shape, { toArrow: "OpenTriangle" })
    // );
    myDiagram.linkTemplateMap.add("auditedLineColor",
        make(go.Link,
            { selectable: false },
            make(go.Shape, { stroke: 'orange', strokeWidth: 2 }),
            make(go.Shape,
                {
                  stroke: 'transparent',
                  strokeWidth: 0,
                  fromArrow: 'Standard',
                  toArrow: 'Standard',
                  fill: 'orange',
                  scale: 1.5
                }
            )
        )
    );

    this.diagram = myDiagram;

    this.updateModel(this.modelData);
  },
  watch: {
    modelData: {
      handler (val) {
        this.updateModel(val);
      },
      deep: true
    }
  },
  methods: {
    model () {
      return this.diagram.model;
    },
    updateModel (val) {
      if (val instanceof go.Model) {
        this.diagram.model = val;
      } else {
        var m = new go.GraphLinksModel()
        if (val) {
          for (var p in val) {
            m[p] = val[p];
          }
        }
        this.diagram.model = m;
      }
    },
    updateDiagramFromData () {
      this.diagram.startTransaction();
      this.diagram.updateAllRelationshipsFromData();
      this.diagram.updateAllTargetBindings();
      this.diagram.commitTransaction("updated");
    },
    // canDeleteSelection () {
    //   for (let it = this.diagram.selection.iterator; it.next();) {
    //     let node = it.value;
    //     if (!(node instanceof go.Node)) return false
    //     let cnode = node.findNodesOutOf()
    //     if (cnode.count) return false;
    //     let pnode = node.findNodesInto()
    //     return pnode.count;
    //   }
    // },

    bdsToZw (bds) {
      if (!bds) return "双击编辑表达式"
      return bds
          .replace(/(\|\|)|(&&)/g, word => {
            let ysf = this.ysfObj[word]
            return "\n" + (ysf || word)
          })
          .replace(/calc\('(\w+)'\)/g, (word, bdsmc, c) => {
            let bdsObj = this.bdsList.find(item => item.bdsmc === bdsmc)
            return bdsObj ? bdsObj.bdsms : word
          })
    }
  }
}
</script>

<style scoped>

</style>
